/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for DSL Editor PowerToy. A copy of the license can be found in the License.htm file
* at the root of this distribution. If you can not locate the Shared Source License
* for DSL Editor PowerToy, please obtain a copy from: http://www.codeplex.com/dsltreegrideditor/Project/License.aspx.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for DSL Editor PowerToy.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;

using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Design;

using DslEditorPowerToy.Controls.Editors.Special.DomainModelTreeGrid.Data;
using DslEditorPowerToy.Languages;

namespace DslEditorPowerToy.Controls.Editors.Special
{
    /// <summary>
    /// Shared description provider
    /// </summary>
    internal class DomainPropertyDescriptionProvider : TypeDescriptionProvider
    {
        #region Constructors
        public DomainPropertyDescriptionProvider()
            : base(TypeDescriptor.GetProvider(typeof(object)))
        {
        }

        #endregion

        #region Public Methods
        protected DomainPropertyTypeDescriptor CreateTypeDescriptor(ICustomTypeDescriptor parent, IDomainProxy domainProxy)
        {
            return new DomainPropertyTypeDescriptor(parent, domainProxy);
        }
        public sealed override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
        {
            //Check if request for static properties
            ICustomTypeDescriptor parent = base.GetTypeDescriptor(objectType, instance);
            if (instance == null)
                return parent;

            //Return dynamic properties
            IDomainProxy domainProxy = instance as IDomainProxy;
            if (null == domainProxy)
                throw new ArgumentOutOfRangeException("instance");

            return this.CreateTypeDescriptor(parent, domainProxy);
        }
        #endregion
    }
    /// <summary>
    /// Shared type descriptor
    /// </summary>
    internal class DomainPropertyTypeDescriptor : CustomTypeDescriptor
    {
        private IDomainProxy _domainProxy = null;

        #region Constructors
        public DomainPropertyTypeDescriptor(ICustomTypeDescriptor parent, IDomainProxy domainProxy)
            : base(parent)
        {
            this._domainProxy = domainProxy;
        }
        #endregion

        #region Public Methods
        public override PropertyDescriptorCollection GetProperties()
        {
            return this.GetProperties(null);
        }
        /// <summary>
        /// Filter avaialbes descriptors based on state of element
        /// </summary>
        /// <param name="attributes"></param>
        /// <returns></returns>
        public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            //Get domain properties for proxy
            ReadOnlyCollection<DomainPropertyInfo> propertiesInfo = this._domainProxy.GetPropertyInfo();
            if (null == propertiesInfo)
                return new PropertyDescriptorCollection(null);

            //Get instance from model element
            ModelElement element = this._domainProxy.Element;
            if (null == element)
                return new PropertyDescriptorCollection(null);
            
            //Create new set of descriptors
            PropertyDescriptorCollection descriptors = new PropertyDescriptorCollection(null);

            //Add special name descriptor for relationships
            if (this._domainProxy is DomainRelationshipProxy)
            {
                DomainRelationshipProxy relationship = this._domainProxy as DomainRelationshipProxy;
                ElementLink link = relationship.Element as ElementLink;

                string linkName = MetaModelHelper.GetRightHandRolePlayerInfo(link).DisplayName;
                descriptors.Add(new TextLabelDescriptor("Name", linkName));
            }

            //Add descriptors for all domain properties
            foreach (DomainPropertyInfo propertyInfo in propertiesInfo)
                descriptors.Add(new ElementPropertyDescriptor(element, propertyInfo, null));

            return descriptors;
        }
        #endregion
    }
}
